import React from 'react';
import PropTypes from 'prop-types';
import Dialog from 'material-ui/Dialog';
import DropDownMenu from 'material-ui/DropDownMenu';
import FlatButton from 'material-ui/FlatButton';
import MenuItem from 'material-ui/MenuItem';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
const propTypes = {
id: PropTypes.string,
/**
* An array of options
*/
options: PropTypes.arrayOf(
PropTypes.shape({
/**
* The checkbox's label
*/
label: PropTypes.string,
/**
* The value of the checkbox. This value
* corresponds to the items specified in the
* `values` property.
*/
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/**
* If true, this checkbox is disabled and can't be clicked on.
*/
disabled: PropTypes.bool
})
).isRequired,
/**
* The value of the input. If `multi` is false (the default)
* then value is just a string that corresponds to the values
* provided in the `options` property. If `multi` is true, then
* multiple values can be selected at once, and `value` is an
* array of items with values corresponding to those in the
* `options` prop.
*/
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string)
]),
/**
* className of the dropdown element
*/
className: PropTypes.string,
/**
* className of the button element
*/
buttonClassName: PropTypes.string,
/**
* Description for the variable
*/
description: PropTypes.string,
/**
* Human name for the variable
*/
humanName: PropTypes.string,
/** Text to display when all values are selected, e.g. 'all ages' */
allValuesText: PropTypes.string,
/**
* If true, the user can select multiple values
*/
multi: PropTypes.bool,
/**
* Dash-assigned callback that gets fired when the input changes
*/
setProps: PropTypes.func
};
const defaultProps = {
multi: false
};
/**
* SDDropdown is an example component.
* It takes a property, `label`, and
* displays it.
* It renders an input with the property `value`
* which is editable by the user.
*/
export default class SDDropdown extends React.Component {
constructor(props) {
super(props);
this.state = {
value: props.value,
editorOpen: false
};
}
componentWillReceiveProps(newProps) {
this.setState({value: newProps.value});
}
get compressedLabel() {
const { options, multi, allValuesText } = this.props;
const { value } = this.state;
Eif (typeof value === 'undefined')
return 'None selected';
let selectedLabels = multi
? options.filter(option => value.indexOf(option.value) > -1)
: options.filter(option => option.value === value);
selectedLabels = selectedLabels.map(option => option.label);
switch (selectedLabels.length) {
case 0:
return 'None selected';
case 1:
return selectedLabels[0];
case options.length:
return typeof allValuesText === 'undefined' ? 'All selected' : allValuesText;
default:
return `${selectedLabels.slice(0, -1).join(', ')} or ${selectedLabels[selectedLabels.length - 1]}`;
}
}
render() {
const { id, options, humanName, buttonClassName, description, setProps, multi } = this.props;
const compressedLabel = this.compressedLabel;
const actions = [
<FlatButton
label="Done editing selection"
primary={true}
onClick={() => { this.setState({editorOpen: false}); }}
/>
];
return (
<MuiThemeProvider>
<div id={id} className="sd-dropdown">
<div className="compressed-label">
<a
href="#edit-dropdown"
onClick={(event) => {
event.preventDefault();
this.setState({editorOpen: true});
}}
className="edit"
>
<span className="label-text">{compressedLabel}</span>
<span className={buttonClassName} />
<span className="edit-rarr">→</span>
</a>
</div>
<Dialog
title={typeof humanName === 'string'
? <h6>Edit options for <strong>{humanName}</strong></h6>
: <h6>Edit options</h6>}
actions={actions}
modal={false}
open={this.state.editorOpen}
onRequestClose={() => { this.setState({editorOpen: false}); }}
>
<div>
<p>{description}</p>
<p>Selected: <strong>{compressedLabel}</strong></p>
<DropDownMenu
value={this.state.value}
onChange={(event, index, value) => {
this.setState({value});
if (setProps) setProps({value});
}}
multiple={multi}
style={{maxWidth: 400}}
>
{
options.map(option => (
<MenuItem
key={option.value}
primaryText={option.label}
value={option.value}
disabled={option.disabled}
/>))
}
</DropDownMenu>
</div>
</Dialog>
</div>
</MuiThemeProvider>);
}
}
SDDropdown.propTypes = propTypes;
SDDropdown.defaultProps = defaultProps;
|